package com.hd.trans.ui.fragment

import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.biubiu.universaladapter.RecyclerViewAdapter
import com.hd.trans.R
import com.hd.trans.TranslationInterior
import com.hd.trans.databinding.FragmentSimulSplitBinding
import com.hd.trans.extension.observe
import com.hd.trans.extension.scrollToBottom
import com.hd.trans.network.bean.TransSubsection
import com.hd.trans.ui.activity.customize.SimulTranslateActivity
import com.hd.trans.ui.adapter.vm.BottomSubsectionVm
import com.hd.trans.ui.adapter.vm.SpaceVm
import com.hd.trans.ui.adapter.vm.TopSubsectionVm
import com.hd.trans.ui.base.DataBindingBaseFragment
import com.hd.trans.ui.base.TransInit
import com.hd.trans.utils.AnimationUtil
import com.hd.trans.utils.ClipboardUtils
import com.hd.trans.utils.ScreenUtil
import com.hd.trans.utils.ToastUtils
import com.hd.trans.utils.preference.Preferences
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.concurrent.atomic.AtomicReference

/**
 * 同声传译合屏时页面
 */
@SuppressLint("SetTextI18n")
class SimulSplitFragment: DataBindingBaseFragment<FragmentSimulSplitBinding>() {
    private var isInitViews: Boolean = false
    private var sysBtnRippleAmin: ObjectAnimator? = null
    private var mUpdateSubsectionRunnable:Runnable? = null

    private val mParent by lazy {
        activity as SimulTranslateActivity
    }

    private val mViewModel by lazy {
        mParent.mViewModel
    }

    private val topTopSpaceVm by lazy {
        SpaceVm(ScreenUtil.dp2px(0f))
    }

    private val mTopContentVm by lazy {
        TopSubsectionVm().apply {
            onContentDisplay = {
                hideTopLoadingViews(it)
            }
        }
    }

    private val mBottomContentVm by lazy {
        BottomSubsectionVm().apply {
            onContentDisplay = {
                hideBottomLoadingViews(it)
            }
        }
    }

    override fun getLayoutId(): Int {
        return R.layout.fragment_simul_split
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        observe()
        super.onCreate(savedInstanceState)
    }

    override fun onDestroy() {
        super.onDestroy()
        sysBtnRippleAmin?.cancel()
    }

    override fun initViewsAndEvents(savedInstanceState: Bundle?) {
        initView()
        initAdapter()
        initData()
    }

    private fun observe() {
        observe(mViewModel.languageFrom) {
            mDataBinding.tvTopSpeakTips.text = TransInit.getLanguageTipsMap()[it.name]?.tips ?: ""
        }
        observe(mViewModel.languageTo) {
            mDataBinding.tvBottomSpeakTips.text = TransInit.getLanguageTipsMap()[it.name]?.tips ?: ""
        }
        observe(mViewModel.voiceState) {
            onRecordingStateChange()
        }
    }

    private fun initView() {
        isInitViews = true
        mDataBinding.apply {
            click = this@SimulSplitFragment
            ivSysSound.alpha = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) 1f else 0.6f

            rlVoicePlayTips.isVisible = Preferences.simultaneousVoicePlayTips
            btnCloseVoicePlayTips.setOnClickListener {
                Preferences.simultaneousVoicePlayTips = false
                rlVoicePlayTips.isVisible = false
            }
            rlVoicePlayTips.setOnClickListener {
                btnCloseVoicePlayTips.performClick()
            }

            updateVoicePlayButton()
            onStateChange()
        }
    }

    private fun initAdapter() {
        mDataBinding.apply {
            rvTop.layoutManager = LinearLayoutManager(mParent)
            rvBottom.layoutManager = LinearLayoutManager(mParent)

            rvTop.adapter = RecyclerViewAdapter(topTopSpaceVm, mTopContentVm, SpaceVm(ScreenUtil.dp2px(60f)))
            rvBottom.adapter = RecyclerViewAdapter(SpaceVm(ScreenUtil.dp2px(40f)), mBottomContentVm)

            rvTop.addOnScrollListener(object : RecyclerView.OnScrollListener(){
                override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                    super.onScrollStateChanged(recyclerView, newState)
                    if (newState == RecyclerView.SCROLL_STATE_IDLE){
                        updateListMaskVisible(updateBottom = false)
                    }
                }
            })

            rvBottom.addOnScrollListener(object : RecyclerView.OnScrollListener(){
                override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                    super.onScrollStateChanged(recyclerView, newState)
                    if (newState == RecyclerView.SCROLL_STATE_IDLE){
                        updateListMaskVisible(updateTop = false)
                    }
                }
            })
        }
    }

    private fun initData() {
    }

    private fun hideTopLoadingViews(hasContent:Boolean){
        if (hasContent){
            //隐藏所有录音波纹动画
            if (mDataBinding.layoutTopSpeak.isVisible){
                mDataBinding.layoutTopSpeak.isVisible = false
                mDataBinding.layoutBottomSpeak.isVisible = false

                mDataBinding.rlLoadingAnimTop.isVisible = true
                mDataBinding.rlLoadingAnimBottom.isVisible = true
            }

            //使顶部复制按钮可用
            mDataBinding.ivCopyIconTop.alpha = 1f
            mDataBinding.rlLoadingAnimTop.isVisible = false
        }
        else{
            mDataBinding.ivCopyIconTop.alpha = 0.6f
            mDataBinding.rlLoadingAnimTop.isVisible = !mDataBinding.layoutTopSpeak.isVisible

        }

    }

    private fun hideBottomLoadingViews(hasContent:Boolean){
        if (hasContent){
            //隐藏所有录音波纹动画
            if (mDataBinding.layoutTopSpeak.isVisible){
                mDataBinding.layoutTopSpeak.isVisible = false
                mDataBinding.layoutBottomSpeak.isVisible = false

                mDataBinding.rlLoadingAnimTop.isVisible = true
                mDataBinding.rlLoadingAnimBottom.isVisible = true
            }

            //使底部复制按钮可用
            mDataBinding.ivCopyIconBottom.alpha = 1f
            mDataBinding.rlLoadingAnimBottom.isVisible = false
        }
        else {
            mDataBinding.ivCopyIconBottom.alpha = 0.6f
            mDataBinding.rlLoadingAnimBottom.isVisible = !mDataBinding.layoutBottomSpeak.isVisible
        }

    }

    /**
     * 更新语音状态
     */
    private fun onRecordingStateChange() {
        val isStop = mViewModel.isStop()

        if (isStop){
            updateVoicePlayButton(false)
        }
        else{
            updateVoicePlayButton()
        }

        mDataBinding.ivBtnStart.isVisible = isStop
        mDataBinding.tvBtnText.isVisible = isStop
        mDataBinding.ivBtnStop.isVisible = !isStop
        mDataBinding.ivBtnPause.isVisible = !isStop
        mDataBinding.tvTimer.isVisible = !isStop

        mDataBinding.ivBtnPause.setImageResource(if (mViewModel.isPause()) R.mipmap.trans_ic_simu_start else R.mipmap.trans_ic_simu_pause)

        updateTranslateTips()
    }

    private fun updateTranslateTips() {
        if (!mDataBinding.layoutTopSpeak.isVisible)
            return

        if (mViewModel.isRecording()){
            //正在录音
            if (mParent.isAllowSaveRecording){ //允许保存录音
                //正在录制音频，点击停止录音
//                TranslateContentConstants.tabToStopRecordingTranslation(mParent.hdLanguageFrom){
//                    if (mParent.isFromLang){
//                        mDataBinding.tvTopSpeakTips.text = it
//                    }
//                    else{
//                        mDataBinding.tvBottomSpeakTips.text = it
//                    }
//                }

                mDataBinding.tvTopSpeakTips.text = ""
                mDataBinding.tvBottomSpeakTips.text = ""
            }
            else{
                //点击停止翻译
//                TranslateContentConstants.tabToStopTranslation(mParent.hdLanguageFrom){
//                    if (mParent.isFromLang){
//                        mDataBinding.tvTopSpeakTips.text = it
//                    }
//                    else{
//                        mDataBinding.tvBottomSpeakTips.text = it
//                    }
//                }
                mDataBinding.tvTopSpeakTips.text = ""
                mDataBinding.tvBottomSpeakTips.text = ""
            }

            if (mViewModel.isFromLang()){
                mDataBinding.waveLineTop.isVisible = true
                mDataBinding.ivTopSpeak.isVisible = false
                mDataBinding.waveLineTop.playAnimation()

            }
            else{
                mDataBinding.waveLineBottom.isVisible = true
                mDataBinding.ivBottomSpeak.isVisible = false
                mDataBinding.waveLineBottom.playAnimation()
            }

        }
        else{
            val langFrom = mViewModel.languageFrom.value
            mDataBinding.tvTopSpeakTips.text = TransInit.getLanguageTipsMap()[langFrom?.name]?.tips ?: ""
            val langTo = mViewModel.languageTo.value
            mDataBinding.tvBottomSpeakTips.text = TransInit.getLanguageTipsMap()[langTo?.name]?.tips ?: ""

            mDataBinding.waveLineTop.pauseAnimation()
            mDataBinding.waveLineBottom.pauseAnimation()
            mDataBinding.waveLineTop.isVisible = false
            mDataBinding.waveLineBottom.isVisible = false
            mDataBinding.ivTopSpeak.isVisible = true
            mDataBinding.ivBottomSpeak.isVisible = true
            mDataBinding.tvTopSpeakTips.isVisible = true
            mDataBinding.tvBottomSpeakTips.isVisible = true

        }

    }

    private fun updateVoicePlayButton(open:Boolean = Preferences.simultaneousVoicePlay){
        if (open && !mViewModel.getHdToLanguage()?.ttsCode.isNullOrEmpty()){
            mParent.setAutoVoicePlay(true)
            mDataBinding.ivVoicePlay.setImageResource(R.drawable.trans_voice_play_gif2)
            mDataBinding.ivVoicePlay.startDrawableAnimation()
        }
        else{
            mParent.setAutoVoicePlay(false)
            mParent.stopPlaying()
            mDataBinding.ivVoicePlay.setImageResource(R.mipmap.ic_voice_close)
        }
    }

    private fun showHideHeadsetTips(show: Boolean){
        mDataBinding.vSysRipple.isVisible = show
        mDataBinding.rlHeadsetTips.isVisible = show

        if (show) {
            if (sysBtnRippleAmin == null) {
                sysBtnRippleAmin =
                    AnimationUtil.heartBeat(mDataBinding.vSysRipple, 0.1f, 2000L)
            }
            sysBtnRippleAmin?.start()
        }else{
            sysBtnRippleAmin?.cancel()
        }
    }

    /**
     * 显示段落
     */
    private val updateSubsectionHolder = AtomicReference<TransSubsection>()
    override fun displaySubsection(data: TransSubsection){
        updateSubsectionHolder.set(data)
        if (mUpdateSubsectionRunnable != null)
            return

        mUpdateSubsectionRunnable = Runnable {
            updateSubsectionHolder.get()?.let { mData ->
                val index = mTopContentVm.indexOf(mData)
                if (index == -1){
                    mTopContentVm.add(mData)
                    mBottomContentVm.add(mData)

                }
                else{
                    mTopContentVm.updateSubsection(mData)
                    mBottomContentVm.updateSubsection(mData)

                }

            }

            mDataBinding.rvTop.scrollToBottom()
            mDataBinding.rvBottom.scrollToBottom()
            updateListMaskVisible()

            mParent.getHandler().removeCallbacks(mUpdateSubsectionRunnable!!)
            mUpdateSubsectionRunnable = null
        }

        mParent.getHandler().postDelayed(mUpdateSubsectionRunnable!!,300)
    }

    private fun updateListMaskVisible(updateTop:Boolean = true,updateBottom:Boolean = true){
        if (updateTop){
            val layoutManager = mDataBinding.rvTop.layoutManager as LinearLayoutManager
            val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
            var top = 0
            var childView: View? = null
            if (firstVisibleItemPosition == 0 && topTopSpaceVm.height == 0){
                if (layoutManager.childCount > 1){
                    childView = layoutManager.getChildAt(1)
                }
            }
            else{
                childView = layoutManager.getChildAt(0)
            }
            childView?.let {
                top = it.top
            }

            mDataBinding.vListMaskTop.isVisible = firstVisibleItemPosition > 1 || top != 0

        }

        if (updateBottom){
            val layoutManager = mDataBinding.rvBottom.layoutManager as LinearLayoutManager
            val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
            var top = 0
            if (firstVisibleItemPosition == 0){
                layoutManager.getChildAt(firstVisibleItemPosition)?.let {
                    top = it.top
                }
            }

            mDataBinding.vListMaskBottom.isVisible = firstVisibleItemPosition != 0 || top != 0
        }
    }

    override fun onStateChange() {
        if(!isInitViews){
            return
        }
        onRecordingStateChange()
        onChronometerTickListener(mParent.recordingDuration)

        updateVoicePlayButton()

        onRotateChanged(mParent.isRotate)

        val subsectionSet = mParent.getSubsectionSet()
        val dataList = subsectionSet.getList()
        mTopContentVm.updateList(dataList)
        mBottomContentVm.updateList(dataList)

        if (mParent.isAndroid10Higher() && !mParent.audioSourceSettings.isRecordSys) {
            showHideHeadsetTips(mParent.mAudioManager.isWiredHeadsetOn())
        }
    }

    override fun onRotateChanged(isRotate: Boolean) {
        val rotationValue = if (isRotate) 180f else 0f
        mDataBinding.topLayout.rotationX = rotationValue
        mDataBinding.topLayout.rotationY = rotationValue
    }

    override fun onChronometerTickListener(timeMillis: Long) {
        val durationStr =  SimpleDateFormat("mm:ss", Locale.getDefault()).format(Date(timeMillis))
        mDataBinding.tvTimer.text = durationStr
    }

    override fun onContentChange(taskId: String) {

        val data = mParent.getSubsectionSet().getItemByTaskId(taskId)
        data?.let {
            displaySubsection(it)
        }
    }

    override fun onDevicesConnect(isConnect: Boolean) {
        showHideHeadsetTips(isConnect)
    }

    override fun onViewClick(v: View?) {
        mDataBinding.apply {
            when(v){
                layoutTopSpeak -> {
                    mParent.startAndStop(true)
                }
                layoutBottomSpeak -> {
                    mParent.startAndStop(true)
                }
                btnRecording -> {

                    if(mViewModel.isStop()){
                        TranslationInterior.getTrackerListener().click(
                            "同声传译",
                            "分屏",
                            "开始录音按钮"
                        )
                        mParent.startAndStop(true)
                    }
                }
                ivBtnPause -> {
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "分屏",
                        if (mViewModel.isRecording()) "暂停录音按钮" else "继续录音按钮"
                    )
                    mParent.startAndPause(true)
                }
                ivBtnStop -> {
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "分屏",
                        "结束录音按钮"
                    )
                    mParent.stopRecording()
                }
                btnVoicePlay -> {
                    val isOpen = !mDataBinding.ivVoicePlay.isPlaying
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "分屏",
                        "${if (isOpen) "开启" else "关闭"}译文播报"
                    )
                    Preferences.simultaneousVoicePlay = isOpen
                    updateVoicePlayButton(isOpen)
                }
                btnSysSound -> {
                    showHideHeadsetTips(false)
                    mParent.showRecordingSettingDialog()
                }
                btnCloseHeadsetTips -> {
                    showHideHeadsetTips(false)
                }
                btnCopyTop -> {
                    if (ivCopyIconTop.alpha != 1f){
                        return
                    }
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "分屏",
                        "复制"
                    )
                    val text = mTopContentVm.getAllContent()
                    if (text.isNotEmpty()) {
                        val isWrite = ClipboardUtils.writeClipText(text)
                        if (isWrite){
                            ToastUtils.showNormal(resources.getString(R.string.copy_success_tips))
                        }
                    }
                }
                btnCopyBottom -> {
                    if (ivCopyIconBottom.alpha != 1f){
                        return
                    }
                    TranslationInterior.getTrackerListener().click(
                        "同声传译",
                        "分屏",
                        "复制"
                    )
                    val text = mBottomContentVm.getAllContent()
                    if (text.isNotEmpty()) {
                        val isWrite = ClipboardUtils.writeClipText(text)
                        if (isWrite){
                            ToastUtils.showNormal(resources.getString(R.string.copy_success_tips))
                        }
                    }
                }
                btnFloatWindow -> {
                    mParent.showFloatWindow()
                }
            }
        }
    }

}